package com.jilefojing.service.impl;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;

import com.jilefojing.beans.data.enums.ResponseEnum;
import com.jilefojing.beans.enums.ItemTypeEnumForSource;
import com.jilefojing.beans.enums.StatusEnumForPublish;
import com.jilefojing.beans.exception.UserContextException;
import com.jilefojing.beans.pojos.RTagSource;
import com.jilefojing.beans.pojos.base.BasePo;
import com.jilefojing.beans.pojos.enhanced.EnhancedRTagSource;
import com.jilefojing.beans.pojos.enhanced.EnhancedTag;
import com.jilefojing.beans.pojos.enhanced.EnhancedUser;
import com.jilefojing.beans.pojos.enhanced.base.BaseEnhanced;
import com.jilefojing.beans.query.RTagSourceQuery;
import com.jilefojing.beans.vo.Pagination;
import com.jilefojing.context.beans.vo.UserContext;
import com.jilefojing.dao.IRTagSourceDao;
import com.jilefojing.service.IRTagSourceService;
import com.jilefojing.service.ISourceService;
import com.jilefojing.service.ITagService;
import com.jilefojing.service.IUserService;
import com.jilefojing.service.base.impl.BaseService;
import com.jilefojing.util.Detect;

/**
 * 
 * @author 作者 jgshun
 * @date 创建时间 2016年07月25日 22时06分59秒
 */
@Service
public class RTagSourceService extends BaseService<RTagSource> implements IRTagSourceService {
	private static final Logger _LOGGER = LoggerFactory.getLogger(RTagSourceService.class);

	@Autowired
	private IRTagSourceDao rTagSourceDao;
	@Autowired
	private ITagService tagService;
	@Autowired
	private IUserService userService;
	@Autowired
	private ISourceService sourceService;

	@Autowired
	private ApplicationContext applicationContext;

	@Override
	public Pagination<EnhancedRTagSource> getPagination(RTagSourceQuery rTagSourceQuery, Pagination<EnhancedRTagSource> pagination, UserContext userContext) {
		Pagination<RTagSource> rTagSourcePagination = rTagSourceDao.getPagination(rTagSourceQuery, pagination.copy());
		pagination.setCount(rTagSourcePagination.getCount());
		if (!Detect.notEmpty(rTagSourcePagination.getItems())) {
			return pagination;
		}
		pagination.setItems(this.conventRTagSources2EnhancedRTagSources(rTagSourcePagination.getItems()));
		this.appendEnhancedCommons2EnhancedRTagSources(pagination.getItems(), userContext);
		return pagination;
	}

	private void appendEnhancedCommons2EnhancedRTagSources(List<EnhancedRTagSource> enhancedRTagSources, UserContext userContext) {
		this.appendEnhancedItem2EnhancedRTagSources(enhancedRTagSources, userContext);
		this.appendEnhancedTags2EnhancedRTagSources(enhancedRTagSources, userContext);
		this.appendEnhancedUsers2EnhancedRTagSources(enhancedRTagSources, userContext);
	}

	@Override
	public List<EnhancedRTagSource> appendEnhancedUsers2EnhancedRTagSources(List<EnhancedRTagSource> enhancedRTagSources, UserContext userContext) {
		List<Long> userIds = new ArrayList<Long>();
		for (EnhancedRTagSource _EnhancedRTagSource : enhancedRTagSources) {
			if (_EnhancedRTagSource.getEnhancedUser() != null) {
				userIds.add(_EnhancedRTagSource.getEnhancedUser().getId());
			}
		}
		if (!Detect.notEmpty(userIds)) {
			return enhancedRTagSources;
		}
		List<EnhancedUser> enhancedUsers = userService.getEnhancedUsers(userIds);
		if (!Detect.notEmpty(enhancedUsers)) {
			return enhancedRTagSources;
		}

		for (EnhancedRTagSource _EnhancedRTagSource : enhancedRTagSources) {
			if (_EnhancedRTagSource.getEnhancedUser() != null) {
				for (EnhancedUser _EnhancedUser : enhancedUsers) {
					if (_EnhancedRTagSource.getEnhancedUser().getId() == _EnhancedUser.getId()) {
						_EnhancedRTagSource.setEnhancedUser(_EnhancedUser);
						break;
					}
				}
			}
		}
		return enhancedRTagSources;
	}

	@Override
	public List<EnhancedRTagSource> conventRTagSources2EnhancedRTagSources(List<RTagSource> rTagSources) {
		List<EnhancedRTagSource> enhancedRTagSources = new ArrayList<EnhancedRTagSource>();
		for (RTagSource _RTagSource : rTagSources) {
			enhancedRTagSources.add(new EnhancedRTagSource(_RTagSource));
		}
		return enhancedRTagSources;
	}

	@Override
	public List<EnhancedRTagSource> getEnhancedRTagSourcesByItem(ItemTypeEnumForSource itemType, long itemId, UserContext userContext) {
		return this.getEnhancedRTagSourcesByItems(itemType, Arrays.asList(new Long[] { itemId }), userContext);
	}

	@Override
	public List<EnhancedRTagSource> getEnhancedRTagSourcesByItems(ItemTypeEnumForSource itemType, List<Long> itemIds, UserContext userContext) {
		RTagSourceQuery rTagSourceQuery = new RTagSourceQuery();
		rTagSourceQuery.setItemIds(itemIds);
		rTagSourceQuery.setItemTypes(Arrays.asList(new ItemTypeEnumForSource[] { itemType }));

		Pagination<EnhancedRTagSource> pagination = new Pagination<EnhancedRTagSource>(1, Integer.MAX_VALUE, false);

		return this.getPagination(rTagSourceQuery, pagination, userContext).getItems();
	}

	@Override
	public List<EnhancedRTagSource> appendEnhancedItem2EnhancedRTagSources(List<EnhancedRTagSource> enhancedRTagSources, UserContext userContext) {
		Map<Class<? extends BasePo>, List<Long>> itemMaps = new HashMap<Class<? extends BasePo>, List<Long>>();

		for (EnhancedRTagSource _EnhancedRTagSource : enhancedRTagSources) {
			if (itemMaps.get(_EnhancedRTagSource.getItemType().getItemClass()) == null) {
				itemMaps.put(_EnhancedRTagSource.getItemType().getItemClass(), new ArrayList<Long>());
			}
			itemMaps.get(_EnhancedRTagSource.getItemType().getItemClass()).add(_EnhancedRTagSource.getEnhancedItem().getDynamicId());
		}

		Set<Entry<Class<? extends BasePo>, List<Long>>> itemEntrys = itemMaps.entrySet();
		for (Entry<Class<? extends BasePo>, List<Long>> _ItemEntry : itemEntrys) {
			this.appendEnhancedItem2EnhancedRTagSources(_ItemEntry, enhancedRTagSources, userContext);
		}
		return enhancedRTagSources;
	}

	private void appendEnhancedItem2EnhancedRTagSources(Entry<Class<? extends BasePo>, List<Long>> itemEntry, List<EnhancedRTagSource> enhancedRTagSources, UserContext userContext) {
		try {
			// WebApplicationContext webApplicationContext =
			// ContextLoader.getCurrentWebApplicationContext();

			Class serviceClass = Class.forName("com.jilefojing.service.I" + itemEntry.getKey().getSimpleName() + "Service");
			Object interfaceImpl = applicationContext.getBean(serviceClass);

			List<BaseEnhanced> enhancedItems = null;
			for (Method _Method : serviceClass.getDeclaredMethods()) {
				if (_Method.getName().equals("getEnhancedsNotAppend")) {
					// enhancedItems = (List<BaseEnhanced>)
					// _Method.invoke(webApplicationContext.getBean(serviceClass),
					// itemEntry.getValue(), userContext);
					enhancedItems = (List<BaseEnhanced>) _Method.invoke(interfaceImpl, itemEntry.getValue(), userContext);
				}
			}

			for (EnhancedRTagSource _EnhancedRTagSource : enhancedRTagSources) {
				for (BaseEnhanced _BaseEnhanced : enhancedItems) {
					if (_EnhancedRTagSource.getItemType().getEnhancedItemClass() == _BaseEnhanced.getClass() && _EnhancedRTagSource.getEnhancedItem().getDynamicId() == _BaseEnhanced.getDynamicId()) {
						_EnhancedRTagSource.setEnhancedItem(_BaseEnhanced);
						break;
					}
				}
			}

		} catch (ClassNotFoundException | BeansException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e1) {
			_LOGGER.error("获取资源Service出错", e1);
		}
	}

	@Override
	public List<EnhancedRTagSource> appendEnhancedTags2EnhancedRTagSources(List<EnhancedRTagSource> enhancedRTagSources, UserContext userContext) {
		List<Long> tagIds = new ArrayList<Long>();
		for (EnhancedRTagSource _EnhancedRTagSource : enhancedRTagSources) {
			tagIds.add(_EnhancedRTagSource.getEnhancedTag().getId());
		}

		@SuppressWarnings("unchecked")
		List<EnhancedTag> enhancedTags = (List<EnhancedTag>) tagService.getEnhanceds(tagIds, userContext);
		if (!Detect.notEmpty(enhancedTags)) {
			return enhancedRTagSources;
		}

		for (EnhancedRTagSource _EnhancedRTagSource : enhancedRTagSources) {
			for (EnhancedTag _EnhancedTag : enhancedTags) {
				if (_EnhancedRTagSource.getEnhancedTag().getId() == _EnhancedTag.getId()) {
					_EnhancedRTagSource.setEnhancedTag(_EnhancedTag);
					break;
				}
			}
		}
		return enhancedRTagSources;
	}

	@Override
	public void update(RTagSource rTagSource, UserContext userContext) throws UserContextException {
		RTagSource dbRTagSource = rTagSourceDao.getById(rTagSource.getId());
		if (dbRTagSource == null) {
			throw new UserContextException("[标签对象不存在]");
		}

		BaseEnhanced enhancedItem = sourceService.getEnhancedItem(ItemTypeEnumForSource.getItemTypeEnumByCode(dbRTagSource.getItemType()), dbRTagSource.getItemId(), userContext);
		if (enhancedItem == null) {
			throw new UserContextException(ResponseEnum.SOURCE_NOT_EXIST);
		}

		short status = dbRTagSource.getStatus();
		if (rTagSource.getStatus() != null && StatusEnumForPublish.getStatusEnumByCode(rTagSource.getStatus()) != null) {
			status = rTagSource.getStatus();
		}

		if (status == StatusEnumForPublish.ALREADY_RELEASED.getCode() && ((StatusEnumForPublish) enhancedItem.get("getStatus")) != StatusEnumForPublish.ALREADY_RELEASED) {
			throw new UserContextException(ResponseEnum.SOURCE_INVALID);
		}

		double sort = dbRTagSource.getSort();
		if (rTagSource.getSort() != null) {
			sort = rTagSource.getSort();
		}

		dbRTagSource.setStatus(status);
		dbRTagSource.setSort(sort);
		dbRTagSource.setUpdateTime(new Date());
		rTagSourceDao.updateByPrimaryKey(dbRTagSource);
	}

}
